<template>
  <div class="player">
    <div id="player-con"></div>
    <view v-if="loading" class="video-loading">
      <u-loading mode="flower" :size="60" :color="globPrimaryColor" v-if="loading"></u-loading>
    </view>
    <view class="video-image" v-if="!loading && sectionDataType == 2">
      <edu-image width="100%" :height="415" :src="detailsInfo.cover_url"></edu-image>
    </view>

    <!-- 防挂机-弹窗 -->
    <prevent-popup
      v-if="detailsInfo.onhook_type == 1"
      ref="refPreventPopupVerify"
      :datas="playerData.onhook"
      @click="onVerifySuccess"
    ></prevent-popup>

    <!-- 防挂机-弹题 -->
    <prevent-question
      v-else-if="detailsInfo.onhook_type == 2"
      ref="refPreventQuestionVerify"
      :course_id="detailsInfo.id"
      :course_type="detailsInfo.course_type"
      @click="onVerifySuccess"
    ></prevent-question>

    <!-- 防挂机-人脸 -->
    <edu-face
      v-else-if="detailsInfo.onhook_type == 3"
      ref="refFaceVerify"
      @confirm="onFaceVerifyConfirm"
      @cancel="onFaceVerifyCancel"
    ></edu-face>
  </div>
</template>
<script>
import { mapState, mapGetters } from 'vuex'
import { uploadFile } from '@/utils/uploadFile.js'
import CCH5BulletScreenComponent from '@/utils/CCH5BulletScreen.js'
import preventQuestion from '../preventQuestion'
import preventPopup from '../preventPopup'
export default {
  props: {
    detailsInfo: {
      type: Object,
      default: () => {},
    },
    course_lock: {
      type: [String, Number],
      default: '',
    },
  },
  components: {
    preventQuestion,
    preventPopup,
  },
  data() {
    return {
      player: null,

      autoplay: false, // 是否自动播放
      continue: false, // 播放完成后是否继续播放下一首，需定义@next事件
      controls: false, // 是否显示默认播放控件
      initialTime: 0, // 指定视频初始播放位置
      current: 0, // 当前进度(s)
      duration: 0, // 总时长(s)
      paused: true, // 是否处于暂停状态
      seek: false, // 是否处于拖动状态
      isFullScreen: false, // 是否处于全屏
      loading: true, //是否处于读取状态
      timer: null, // 计时器

      currentDuration: 0, // 记录学习时长

      previewEnd: false, // 试看状态
      previewDuration: 0, // 视频试看时长

      faceModalVisible: false, // 人脸验证弹出
      faceVerifyStart: false,
      faceVerifyEnd: true, // 人脸验证结束
      faceVerifyNumber: 0, // 还需要验证次数
      faceIntervalTime: 0, //见时间间隔
      faceNextVerifyTime: 0, // 下一次验证时间
      faceSceneType: 2, // 场景
      faceSceneId: 0, // 验证id
      faceShootStatus: false, // 续播状态

      playerData: {}, // 播放数据
    }
  },
  computed: {
    ...mapGetters({
      globPrimaryColor: 'designSetting/getGlobThemeColor',
      accountInfo: 'user/getUserInfo',
    }),
    ...mapState({
      getCurrentPlayItem: (state) => state.course.currentPlayItem, // 课时数据
    }),
    sectionDataType() {
      return this.getCurrentPlayItem.section_data.data_type || 1
    },
  },
  methods: {
    createPlayer(params) {
      let openMobileLandscape = false
      let platform = uni.getSystemInfoSync().platform
      if (platform == 'android') {
        openMobileLandscape = true
      } else {
        openMobileLandscape = false
      }
      let props = {
        autoStart: this.autoplay,
        width: '100%',
        height: '100%',
        playtype: 1,
        isShare: false, // 显示分享界面
        isShowUrlBtn: false, // 是否显示切换线路按钮
        isShowMoreBtn: false, // 是否显示右上角更多按钮
        forceShowVote: false, // 关闭强制显示答题器
        isShowExercise: false, // 是否显示课堂练习
        isShowVisitor: false, // 是否显示访客信息收集器
        isShowQuestions: false, // 是否显示问答
        isShowRightMenu: false, // 控制显示右侧菜单是否显示
        open_barrage: false, // 是否开启弹幕
        closeHistoryTime: 1, // 置是否关闭记忆播放功能。0，使用； 1，关闭
        mobileFullsMarquee: true, // 设置是否开启移动端字幕跑马灯。true，开启； false，关闭
        openMobileLandscape: openMobileLandscape, // 允许横屏 ios全屏有问题
        parentNode: '#player-con',
        freeTimeTip: {
          msg: '观看完整视频,请先购买课程',
          linkText: '去购买',
          linkUrl: 'javascript:void(0)',
          target: '_self', // 在何处打开链接_blank 、 _self
        }, // 试看中文案提示
        freeTimeEndTip: {
          msg: '试看已结束',
          linkText: '去购买',
          linkUrl: 'javascript:void(0)',
          target: '_self', // 在何处打开链接_blank 、_self
        }, // 试看结束文案提示
        ...params,
      }
      this.player = window.createCCH5Player(props)
    },
    setPlayerCallBack() {
      window.onCCH5PlayerLoaded = this.onPlayerLoaded
      window.on_CCH5player_ready = this.onPlayerReady
      window.on_CCH5player_play = this.onPlayerPlay
      window.on_CCH5player_pause = this.onPlayerPause
      window.on_CCH5player_ended = this.onPlayerEnded
      window.on_player_timeupdate = this.onPlayerTimeupdate
      window.on_player_seek = this.onPlayerSeek
      window.on_player_fullscreen = this.onPlayerFullscreen
    },
    // 播放下一个视频
    nextPlayer() {
      this.paused = true
      this.current = 0
      this.autoplay = true
      this.$store.commit('course/setCurrentPlayItem', {
        ...this.getCurrentPlayItem,
        ...this.playerData.next_position,
      })
      if (this.player) {
        this.player.pause()
        this.player.destroy() // 销毁
      }
      this.$emit('next')
    },
    /***
     * 播放器js文件加载完成的回调
     */
    onPlayerLoaded() {
      window.ccH5PlayerJsLoaded = true
    },
    /**
     * 播放器初始化完成即将播放时回调
     */
    onPlayerReady() {
      // 防挂机
      const marqueeData = this.playerData.marquee
      if (!this.$u.test.empty(marqueeData)) {
        // dom插入版权声明
        if (marqueeData.copyright == 1) {
          let content = document.createElement('div')
          content.className = 'ccH5copyrightBox'
          let c = document.createElement('div')
          c.className = 'notice-content'
          let t = document.createElement('span')
          t.className = 'notice-text'
          t.innerHTML = marqueeData.copyright_content
          c.append(t)
          content.append(c)
          document.querySelector('#player-con .ccH5playerBox').append(content)

          let rightBoxHtml = document.querySelector('#player-con .ccH5playerBox .ccH5copyrightBox')
          let noticeHtml = document.querySelector(
            '#player-con .ccH5playerBox .ccH5copyrightBox .notice-content'
          )
          noticeHtml.addEventListener('animationiteration', () => {
            rightBoxHtml.style.opacity = 0
            noticeHtml.style.animationPlayState = 'paused'
            setTimeout(() => {
              rightBoxHtml.style.opacity = 1
              noticeHtml.style.animationPlayState = 'running'
            }, marqueeData.frequency * 1000)
          })
        }

        // 跑马灯
        if (this.sectionDataType == 1) {
          let marqueeContent = ''
          let name = ''
          let phone = ''
          if (marqueeData.username == 1) name = this.accountInfo.nick_name || ''
          if (marqueeData.phone == 1) phone = this.accountInfo.phone || ''
          marqueeContent = name + phone
          if (marqueeContent) {
            this.CCH5BulletScreen = new CCH5BulletScreenComponent(
              '#player-con .ccH5playerBox',
              marqueeContent,
              {
                fontSize: `${marqueeData.font_size}px`,
                color: this.$edu.test.hexToRgba(marqueeData.font_color, marqueeData.font_opacity),
              },
              'top',
              marqueeData.frequency
            )

            this.CCH5BulletScreen && this.CCH5BulletScreen.ready()
          }
        }
      }

      setTimeout(() => {
        this.duration = this.player.getDuration()

        // 初始化验证
        this.handleVerifyInit()

        // 绑定试看点击事件
        this.onPreviewDurationPay()
      }, 600)
    },
    /**
     * 播放时回调
     */
    onPlayerPlay() {
      this.paused = false
      clearInterval(this.timer)
      this.timer = setInterval(() => {
        this.currentDuration++
        if (this.currentDuration % 10 == 0) {
          this.handleAddLearning()
        }
      }, 1000)
      this.onVerifyTimeupdate()

      this.CCH5BulletScreen && this.CCH5BulletScreen.playing()
    },
    /**
     * 暂停播放时回调
     */
    onPlayerPause() {
      this.paused = true
      clearInterval(this.timer)
      this.handleAddLearning()

      this.CCH5BulletScreen && this.CCH5BulletScreen.pause()
    },
    /**
     * 播放结束时回调
     */
    onPlayerEnded() {
      clearInterval(this.timer)
      this.handleAddLearning()
      // 顺序模式
      if (this.course_lock == 1) return
      if (this.continue) {
        // 获取当前屏幕全屏状态
        let isFullScreen = this.player && this.player.isFullScreen()

        // 退出全屏播放
        if (isFullScreen) this.player.normalScreen()

        //  人脸开关
        if (this.detailsInfo.onhook_type == 3) {
          this.handleModalConfirm()
          this.faceSceneType = 1
          this.faceSceneId = this.playerData.next_position.id
          this.faceShootStatus = true
        } else {
          this.nextPlayer()
        }
      } else {
        this.paused = true
        this.current = 0
      }
    },
    /**
     * 播放位置发生改变时回调
     * currentTime： 当前播放时间
     */
    onPlayerTimeupdate(currentTime) {
      if (!this.seek) {
        this.current = Math.floor(currentTime)
      }
      this.onVerifyTimeupdate() // 人脸
      this.onPreviewDurationEnd(currentTime) // 处理试看
    },
    /**
     * 拖动或点击进度条改变播放进度时回调
     * prevTime: 进度变化前时间
     * currentTime: 视频进度变化后时间
     */
    onPlayerSeek(prevTime, currentTime) {},
    // 播放器退出全屏或变全屏时回调
    onPlayerFullscreen(mode) {
      let ccH5playerBox = document.querySelector('#player-con .ccH5playerBox .ccH5copyrightBox')
      if (mode == 1) {
        document.querySelector('#player-con').style.zIndex = '1001'
        ccH5playerBox.style.left = uni.upx2px(20) + 'px'
        ccH5playerBox.style.right = uni.upx2px(20) + 'px'
      } else {
        document.querySelector('#player-con').style.zIndex = '900'
        ccH5playerBox.style.left = uni.upx2px(100) + 'px'
        ccH5playerBox.style.right = uni.upx2px(190) + 'px'
      }
    },
    // 获取播放地址
    async getPlayerFile(palyData) {
      this.playerData = palyData
      this.continue =
        !this.$u.test.empty(palyData.next_position) &&
        !this.$u.test.empty(palyData.next_position.position)

      if (this.detailsInfo.onhook_type == 3) {
        this.faceSceneId = this.getCurrentPlayItem.id
      }

      this.$edu.api
        .getCourseSectionVideo(
          this.getCurrentPlayItem.course_id,
          this.getCurrentPlayItem.id,
          this.getCurrentPlayItem.section_data.stock
        )
        .then((res) => {
          const { data } = res
          this.handleAuditionTime() // 计算试听时长
          this.handleInitialTime()

          let params = {
            vid: data.videoid,
            siteid: data.userid,
          }
          // 试看位置
          if (this.previewDuration > 0) {
            params = {
              ...params,
              freeTime: this.previewDuration,
            }
          }
          // 指定视频指定位置
          if (this.initialTime > 0) {
            params = {
              ...params,
              watchStartTime: this.initialTime,
            }
          }
          this.player && this.player.destroy() // 销毁
          this.createPlayer(params) // 创建播放器
          this.loading = false
        })
    },
    // 计算试听时长
    handleAuditionTime() {
      this.previewEnd = false
      let buy = this.getCurrentPlayItem.is_buy
      if (this.$edu.test.isDef(buy) && buy == 0) {
        let audition = this.getCurrentPlayItem.audition || 0
        let duration = this.getCurrentPlayItem.section_data.duration || this.duration || 0
        this.previewDuration = Math.round(duration * (audition / 100))
      }
    },
    // 处理试看结束
    onPreviewDurationEnd(currentTime) {
      if (!this.previewEnd && this.previewDuration !== 0 && this.previewDuration < this.duration) {
        if (Math.floor(this.previewDuration) < currentTime) {
          let isFullScreen = this.player && this.player.isFullScreen() // 获取当前屏幕全屏状态
          if (isFullScreen) this.player.normalScreen() // 退出全屏播放
          this.previewEnd = true
          this.player.jumpToTime(this.previewDuration) // 跳转到某个时间点播放
          this.player.pause()
        }
      }
    },
    // 试看购买
    onPreviewDurationPay() {
      const _this = this
      let previewDefaultEleBtn = document.querySelector(
        '#player-con .CCH5playerContainer .ccH5FreeTimeTipBox a'
      )
      if (previewDefaultEleBtn) {
        previewDefaultEleBtn.onclick = function () {
          _this.$u.route({
            type: 'redirectTo',
            url: '/pageCourse/cart/course',
            params: {
              id: _this.getCurrentPlayItem.course_id,
            },
          })
        }
      }

      document.querySelector('#player-con').addEventListener(
        'click',
        function () {
          let item = document.querySelector('.CCH5playerContainer .ccH5TipBtn')
          if (item) {
            _this.$u.route({
              type: 'redirectTo',
              url: '/pageCourse/cart/course',
              params: {
                id: _this.getCurrentPlayItem.course_id,
              },
            })
          }
        },
        false
      )
    },
    // 断点续播
    handleInitialTime() {
      let buy = this.getCurrentPlayItem.is_buy
      let time = this.getCurrentPlayItem.section_rate.current_time
      if (this.$edu.test.isDef(buy) && buy == 0) return
      this.initialTime = time
      this.current = this.initialTime
    },
    /* 人脸 START */
    handleVerifyInit() {
      // 课时是否购买
      let buy = this.getCurrentPlayItem.is_buy
      if (this.$edu.test.isDef(buy) && this.getCurrentPlayItem.is_buy == 0) return

      // 是否是视频
      if (this.$edu.test.isDef(this.sectionDataType) && this.sectionDataType != 1) return

      // 是否开启验证
      if (this.detailsInfo.onhook_type == 0) return

      this.timer = null

      this.faceSceneType = 2
      this.faceShootStatus = false
      this.faceVerifyEnd = false
      this.faceNextVerifyTime = 0
      if (this.detailsInfo.onhook_type == 1) {
        const onhookData = this.playerData.onhook
        this.faceVerifyNumber = onhookData.alert_max_number // 验证次数
        this.faceIntervalTime = onhookData.alert_time_interval * 60 // 时间间隔
      } else if (this.detailsInfo.onhook_type == 2) {
        const examData = this.playerData.onhook_exam
        this.faceVerifyNumber = examData.answer_max_number // 验证次数
        this.faceIntervalTime = examData.answer_time_interval * 60 // 时间间隔
      } else if (this.detailsInfo.onhook_type == 3) {
        const faceData = this.playerData.face_data
        this.faceVerifyNumber = faceData.need_verify_number // 验证次数
        this.faceIntervalTime = faceData.verify_timespan * 60 // 时间间隔
      }

      this.nextVerifyTime()
    },
    // 计算下一次验证时间
    nextVerifyTime() {
      if (this.faceVerifyNumber > 0) {
        let time = this.currentDuration + this.faceIntervalTime
        this.faceNextVerifyTime = time
      } else {
        this.faceVerifyEnd = true
      }
    },
    // 播放时弹出人脸
    onVerifyTimeupdate() {
      if (
        !this.faceVerifyEnd &&
        this.faceNextVerifyTime > 0 &&
        this.faceNextVerifyTime <= this.currentDuration
      ) {
        uni.$u.debounce(
          () => {
            let isFullScreen = this.player && this.player.isFullScreen() // 获取当前屏幕全屏状态
            if (isFullScreen) this.player.normalScreen() // 退出全屏播放
            if (this.detailsInfo.onhook_type == 1) {
              this.$refs.refPreventPopupVerify.onOpen()
            } else if (this.detailsInfo.onhook_type == 2) {
              this.$refs.refPreventQuestionVerify.onOpen()
            } else if (this.detailsInfo.onhook_type == 3) {
              this.handleModalConfirm()
            }
            this.player.pause()
          },
          1000,
          true
        )
      }
    },
    // 去验证人脸
    handleModalConfirm() {
      if (this.faceVerifyStart) return
      this.faceVerifyStart = true
      this.$refs.refFaceVerify.onFaceMessage()
    },
    // 提交人脸验证
    onFaceVerifyConfirm(file) {
      uploadFile('/user/tencent/face/person/verify', file, {
        scene_key: 'course_section',
        scene_id: this.faceSceneId,
        scene_type: this.faceSceneType,
      })
        .then((res) => {
          this.$u.toast(res.msg)
          this.$refs.refFaceVerify.onClose()
          this.onVerifySuccess()
        })
        .catch((err) => {
          console.log(err)
          this.$u.toast(err.msg)
          this.$refs.refFaceVerify.resetPhoto()
        })
    },
    // 取消
    onFaceVerifyCancel() {
      this.faceVerifyStart = false
    },
    // 人脸验证成功
    onVerifySuccess() {
      // 续播
      if (this.faceShootStatus) {
        this.nextPlayer()
      } else {
        this.faceVerifyNumber-- // 还需要验证次数
        this.nextVerifyTime()
        this.player.play() // 视频播放
      }
      this.faceVerifyStart = false
    },
    // 添加学习记录
    handleAddLearning() {
      let buy = this.getCurrentPlayItem.is_buy
      if (this.$edu.test.isDef(buy) && buy == 0) return
      this.$edu.api.createCourseRecord({
        course_id: this.getCurrentPlayItem.course_id,
        section_id: this.getCurrentPlayItem.id,
        current_time: this.current,
      })
    },
    // 生成随机数
    random(m, n) {
      m = m || 1
      n = n || 100
      if (m >= n) {
        n = m + 100
      }
      let w = n - m
      let num = Math.random() * w + m
      return Math.round(num)
    },
  },
  mounted() {
    this.setPlayerCallBack()
    // 暂停播放
    uni.$on('sectionPlayerPause', () => {
      if (this.player) {
        this.player.pause()
      }
    })
  },
  destroyed() {
    this.player = null
  },
}
</script>
<style lang="scss" scoped>
.player {
  color: #fff;
  width: 100%;
  height: 100%;
  overflow: hidden;
  position: relative;
  background-color: #000;
  #player-con {
    width: 100%;
    height: 100%;
    position: relative;
  }
  .video-loading {
    position: absolute;
    left: 0;
    right: 0;
    bottom: 0;
    top: 0;
    z-index: 100;
    background-color: #000000;
    display: flex;
    align-items: center;
    justify-content: center;
  }
  .video-image {
    position: absolute;
    left: 0;
    top: 0;
    width: 100%;
    height: 100%;
    z-index: 1;
  }
}
::v-deep .ccH5AudioBg {
  width: 100%;
  height: 100%;
  opacity: 0;
}

::v-deep .ccH5copyrightBox {
  position: absolute;
  top: 20rpx;
  left: 100rpx;
  right: 190rpx;
  z-index: 99;
  background: rgba(0, 0, 0, 0.2);
  overflow: hidden;
  display: flex;
  .notice-content {
    animation: cch5-loop-animation 10s linear infinite both;
    text-align: right;
    padding-left: 100%;
    display: flex;
    flex-wrap: nowrap;
    box-sizing: border-box;
  }
  .notice-text {
    font-size: 24rpx;
    font-weight: 400;
    color: #ffffff;
    line-height: 52rpx;
    word-break: keep-all;
    white-space: nowrap;
  }
}

#player-con .bullet-screen {
  position: absolute;
  white-space: nowrap;
  animation: bullet 6s linear infinite;
  right: 0;
  z-index: 101;
  transform: translateX(100%);
}

@keyframes bullet {
  from {
    right: 0;
    transform: translateX(100%);
  }
  to {
    right: 100%;
    transform: translateX(-100%);
  }
}

@keyframes cch5-loop-animation {
  0% {
    transform: translate3d(0, 0, 0);
  }

  100% {
    transform: translate3d(-100%, 0, 0);
  }
}
</style>
